/**
* @file http_test.c
* Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* <DESC>
 * Simple HTTP/HTTPS GET
 * </DESC>
 */ 
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

#include "stdbool.h"
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "http/httpclient.h"

#include "ohos_types.h"
#include "http_test.h"

#define  TESTS_FS_IO_EN  0

#define HTTP_CLIENT_BUFFER_SIZE       1024//512

#define UNUSED(var) do { (void)var; } while(0)

#define DBG_LINE_PRINT(strFmt, args...) printf("%s[%d]"strFmt"\n", __FILE__, __LINE__, ##args)

static int http_download_request(char *fileuri, char* fileName){
  uint32  nRetCode;
  HTTPCLIENT_SESSION_HANDLE pHTTP;
	#if TESTS_FS_IO_EN
  	FILE *input;

	input = fopen(fileName ,"r");
	if (input != NULL){
		DBG_LINE_PRINT("[ERROR]file already existing[%s].\n", fileName);
		return HOS_FAILURE;
	}
	//input = freopen(filePath ,"w", input);
	input = fopen(fileName ,"w");
	if (input == NULL){
		DBG_LINE_PRINT("[ERROR]file create fail[%s].\n", fileName);
		return HOS_FAILURE;
	}
	#else
	UNUSED(fileName);
	#endif

	/* Open the HTTP request handle */
	pHTTP = httpclient_open(0);
	/* Set the Verb */
	if(HTTPCLIENT_SUCCESS != (nRetCode = httpclient_set_verb(pHTTP, HTTPCLIENT_GET))) {
		DBG_LINE_PRINT("[ERROR]httpclient_set_verb error [%d].\n", nRetCode);
		#if TESTS_FS_IO_EN
		fclose(input);
		remove(fileName);
		#endif
		httpclient_close(&pHTTP);
		return HOS_FAILURE;
	}

	/* [TODO]Set authentication */

	/* Send a post request to file server. */
	if(HTTPCLIENT_SUCCESS != (nRetCode = httpclient_send_request(pHTTP,  fileuri, NULL, 0, 0, -1, 0))) {
		DBG_LINE_PRINT("[ERROR]httpclient_send_request error [%d].\n", nRetCode);
		#if TESTS_FS_IO_EN
		fclose(input);
		remove(fileName);
		#endif
		httpclient_close(&pHTTP);
		return HOS_FAILURE;
	}

	// Retrieve the the headers and analyze them
	if(HTTPCLIENT_SUCCESS != (nRetCode = httpclient_recv_response(pHTTP,3))) {
		DBG_LINE_PRINT("[ERROR]httpclient_recv_response error [%d].\n", nRetCode);
		#if TESTS_FS_IO_EN
		fclose(input);
		remove(fileName);
		#endif
		httpclient_close(&pHTTP);
		return HOS_FAILURE;
	}

	httpclient_t pHTTPClient;
	httpclient_get_info(pHTTP, &pHTTPClient);
	DBG_LINE_PRINT("Response HTTPStatusCode: %d", pHTTPClient.HTTPStatusCode);
	if (200 > pHTTPClient.HTTPStatusCode || 300 <= pHTTPClient.HTTPStatusCode) {
		#if TESTS_FS_IO_EN
		fclose(input);
		remove(fileName);
		#endif
		DBG_LINE_PRINT("\n\nHTTP Client Info:\n\tHTTPStatusCode: %d\n\tRequestBodyLengthSent: %d\n\tResponseBodyLengthReceived: %d\n\tTotalResponseBodyLength: %d\n\tHttpState: %d",
		pHTTPClient.HTTPStatusCode, pHTTPClient.RequestBodyLengthSent, pHTTPClient.ResponseBodyLengthReceived, pHTTPClient.TotalResponseBodyLength, pHTTPClient.HttpState);

		httpclient_close(&pHTTP);
		return HOS_FAILURE;
	}
	DBG_LINE_PRINT("extracted recv data:%d Bytes", pHTTPClient.TotalResponseBodyLength);
	if (pHTTPClient.TotalResponseBodyLength) {
		uint32 nSize,nTotal = 0;
		char *pBuffer = (char *)malloc(HTTP_CLIENT_BUFFER_SIZE + 1);
		if (!pBuffer) {
			httpclient_close(&pHTTP);
			return HOS_FAILURE;
		}

		// Get the data until we get an error or end of stream code
		// DBG_LINE_PRINT("Each dot represents %d bytes:\n",HTTP_BUFFER_SIZE );
		while(HTTPCLIENT_SUCCESS == nRetCode || HTTPCLIENT_EOS != nRetCode) {
			// Set the size of our buffer
			nSize = HTTP_CLIENT_BUFFER_SIZE;
			// Get the data
			nRetCode = httpclient_receive_data(pHTTP, pBuffer, nSize, -1, &nSize);
			if (HTTPCLIENT_SUCCESS != nRetCode && HTTPCLIENT_EOS != nRetCode) {
				DBG_LINE_PRINT("httpclient_receive_data error:%d", nRetCode);
				break;//continue;
			}
			//DBG_LINE_PRINT("httpclient_receive_data:%d Bytes", nSize);
			/* write data to file */
			int wlen = 0 ,wtlen = 0;
			while(wtlen < (int)nSize || wlen < 0) {
				#if TESTS_FS_IO_EN
				wlen = fwrite(pBuffer+wtlen, 1, nSize, input);
				#else
				wlen = nSize;
				#endif
				wtlen += wlen;
			}
			if (wlen != (int)nSize) {
				nRetCode = HOS_FAILURE;
				break;
			}
			printf(".");

			nTotal += nSize;
			// Print out the results
			//DBG_LINE_PRINT("%s", Buffer);
		}
		if (HTTPCLIENT_EOS == nRetCode) {
			nRetCode = HOS_FAILURE;
		}
		#if TESTS_FS_IO_EN
		fclose(input);
		#endif
		//DBG_LINE_PRINT("nTotal:%d Bytes", nTotal);
		httpclient_get_info(pHTTP, &pHTTPClient);
		//DBG_LINE_PRINT("received data:%d Bytes", pHTTPClient.ResponseBodyLengthReceived);
		if (pHTTPClient.TotalResponseBodyLength != nTotal) {
			DBG_LINE_PRINT("Response Buffer Length Error: extracted %d but received %d", pHTTPClient.TotalResponseBodyLength, nTotal);
			#if TESTS_FS_IO_EN
			remove(fileName);
			#endif
			httpclient_close(&pHTTP);
			return HOS_FAILURE;
		}
	}
	httpclient_close(&pHTTP);

	return nRetCode;
}

static int http_DownloadFile(char* fileuri, char* filename){
  uint32 nRetCode = HOS_SUCCESS;

	DBG_LINE_PRINT("[INFO]GET File %s.\n", fileuri);

	nRetCode = http_download_request(fileuri, filename);

	return nRetCode;
}

int httpTestHttpsGet(void)
{
   return http_DownloadFile("https://www.baidu.com/img/flexible/logo/pc/result.png", "dest_htttps_file.png");
}

int httpTestHttpGet(void)
{
   return http_DownloadFile("http://images.blogjava.net/blogjava_net/heis/snakematrix/0aac7dcf-6a61-3678-a0e4-45e7220da9ac.jpg", "dest_http_file.jpg");
}